﻿using NClass.Core;
using System;
using System.Collections.Generic;

namespace NClass.TestHelper
{
	public static class Resolver
	{
		public enum Language { CSharp, Java, StubLanguage }

        public static Resolver.Language GetResolverLanguage(Resolver.Language language)
        {
#if STUB
            return Resolver.Language.StubLanguage;
#else
           return language;
#endif
        }

		public static NClass.Core.Language GetLanguage(Resolver.Language language)
		{
			try
			{
#if STUB
				language = Language.StubLanguage;
#endif
				return NClass.Core.Language.GetLanguage(language.ToString());
			}
			catch (Exception ex)
			{
				throw new Exception(string.Format("Unsupported language: {0}", language.ToString()), ex);
			}
		}

		public static NClass.Core.Model CreateModel(Resolver.Language language)
		{
			NClass.Core.Language classLanguage = null;
			return CreateModel(language, out classLanguage);
		}

		public static NClass.Core.Model CreateModel(Resolver.Language language, out NClass.Core.Language classLanguage)
		{
			classLanguage = GetLanguage(language);
			return new NClass.Core.Model(classLanguage);
		}

		public static NClass.Core.StructureType CreateStruct(Resolver.Language language, out NClass.Core.Language structLanguage, out NClass.Core.Model model)
		{
			model = CreateModel(language, out structLanguage);
			return model.AddStructure();
		}

		public static NClass.Core.ClassType CreateClass(Resolver.Language language, out NClass.Core.Language classLanguage, out NClass.Core.Model model)
		{
			model = CreateModel(language, out classLanguage);
			return model.AddClass();
		}

		public static NClass.Core.ClassType CreateClass(Resolver.Language language)
		{
			NClass.Core.Language classLanguage = null;
			NClass.Core.Model model = null;
			return CreateClass(language, out classLanguage, out model);
		}

		public static Dictionary<string, NClass.Core.ClassType> CreateClasses(Resolver.Language language, out NClass.Core.Model model, params string[] classNames)
		{
			NClass.Core.Language classLanguage = null;
			model = CreateModel(language, out classLanguage);

			var classes = new Dictionary<string, NClass.Core.ClassType>();

			foreach (var className in classNames)
			{
				if (string.IsNullOrWhiteSpace(className))
					continue;
				if (classes.ContainsKey(className))
					throw new Exception("Class names must be unique");
				var newClass = model.AddClass();
				newClass.Name = className;
				classes.Add(className, newClass);
			}

			return classes;
		}

		public static IEntity GetEntity(Model model, string entityName, Func<Model, string, IEntity> createEntity = null)
		{
			if (model == null)
				throw new ArgumentNullException("model");

			foreach (var entity in model.Entities)
			{
				if (string.Equals(entity.Name, entityName, StringComparison.CurrentCulture))
					return entity;
			}

			if (createEntity != null)
				return createEntity(model, entityName);

			return null;
		}
	}
}
